package com.UBC417.termproject.Data;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Logger;

import com.UBC417.termproject.Servlet.SubscribeServlet;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.SortDirection;

@SuppressWarnings("deprecation")
public class Buyer extends User {
	private static final Logger log = Logger.getLogger(SubscribeServlet.class.getName());
	
	public static List<Item> SearchItem(String ItemName){
		DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
		
		Query query = new Query("Item").addFilter("status", Query.FilterOperator.EQUAL, "Open");
		Iterable<Entity> entries = ds.prepare(query).asIterable();
		List<Item> items = new ArrayList<Item>();
		for(Entity e : entries){
			String str = (String) e.getProperty("name");
			if (str.toLowerCase().contains(ItemName.toLowerCase())){
				Item item = new Item();
				item.setBasePrice((Double)e.getProperty("basePrice"));
				item.setAuctionId((String)e.getProperty("auctionId"));
				item.setDescription((String)e.getProperty("description"));
				item.setName((String)e.getProperty("name"));
				items.add(item);
			}
		}
		return items;
	}
	
	public static void BidItem(String auctionId, String price, String userId){
		DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
		
		Key key = KeyFactory.stringToKey(auctionId);
		try {
			Entity auction = ds.get(key);
			String itemName = (String) auction.getProperty("name");
			
			// put new bid
			Entity e = new Entity("Bid");
			Date d = new Date();
			e.setProperty("auctionId", auctionId);
			e.setProperty("dateCreated", d);
			e.setProperty("userId",userId);
			e.setProperty("price", Double.parseDouble(price));
			e.setProperty("itemName", itemName);
			
			ds.put(e);
		} catch (EntityNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		
		
	}
	
	public static void SetRating(String buyerId, String sellerId, String rating){
		DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
		
		Entity e = new Entity("Rating");
		Date d = new Date();
		
		e.setProperty("buyerId", buyerId);
		e.setProperty("sellerId", sellerId);
		e.setProperty("dateCreated", d);
		e.setProperty("rating",Double.parseDouble(rating));
		
		ds.put(e);
	}
	
	public static Double GetRating(String sellerId){
		DatastoreService ds = DatastoreServiceFactory.getDatastoreService();

		Query query = new Query("Rating").addFilter("sellerId", Query.FilterOperator.EQUAL, sellerId);
		Iterable<Entity> ratings = ds.prepare(query).asIterable();
		double rating = 0;
		int count = 0;
		for (Entity e : ratings){
			 double val = (Double)e.getProperty("rating");
			 rating = rating + val;
			 count++;
		}
		return (rating/count);
	}
	
	public static List<Comment> GetComment(String sellerId){
		DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
		Query query = new Query("Comment").addFilter("sellerId", Query.FilterOperator.EQUAL, sellerId);
		Iterable<Entity> entries = ds.prepare(query).asIterable();
		List<Comment> com = new ArrayList<Comment>();
		for (Entity e : entries){
			Comment c = new Comment();
			c.setBuyerId((String)e.getProperty("buyerId"));
			c.setSellerId((String)e.getProperty("sellerId"));
			c.setContent((String)e.getProperty("content"));
			c.setDateCreated((Date)e.getProperty("dateCreated"));
			com.add(c);
		}
		return com;
	}
	
	public static Comment SetComment(String buyerId, String sellerId, String content){
		DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
		
		// put new comment
		Entity e = new Entity("Comment");
		Date d = new Date();
		e.setProperty("buyerId", buyerId);
		e.setProperty("sellerId", sellerId);
		e.setProperty("dateCreated", d);
		e.setProperty("content",content);
		
		ds.put(e);
		
		Comment c = new Comment();
		c.setBuyerId(buyerId);
		c.setContent(content);
		c.setDateCreated(d);
		c.setSellerId(sellerId);
		
		return c;
	}
	
	public static List<String> getSellerFromAuctionId(List<Bid> bids){
		DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
		List<String> list = new ArrayList<String>();
		for (Bid b : bids){
			try {
				String str = b.getAuctionId();
				Entity e = ds.get(KeyFactory.stringToKey(str));
				if (!list.contains((String) e.getProperty("userId"))){
					list.add((String) e.getProperty("userId"));
				}				
			} catch (EntityNotFoundException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
		
		return list;
	}
	
	public static List<Auction> GetRecommendations(String buyerId){
		// pick one item from each of the seller this buyer has bought stuff from
		// only pick from top 10 or less
		DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
		
		List<Bid> recent = ShowHistory(buyerId);
		List<Auction> results = new ArrayList<Auction>();
		List<String> recentSeller = getSellerFromAuctionId (recent);
		
		for (int i=0; i<Math.min(recentSeller.size(), 10); i++){
			Query query = new Query("Auction").addFilter("userId", Query.FilterOperator.EQUAL, recentSeller.get(i)).addFilter("status", Query.FilterOperator.EQUAL, "Open").addSort("dateCreated",SortDirection.DESCENDING);
			Iterable<Entity> entities = ds.prepare(query).asIterable(FetchOptions.Builder.withLimit(1));
			for (Entity e : entities){
				Auction a = new Auction();
				a.setName((String)e.getProperty("name"));
				a.setUserId((String)e.getProperty("userId"));
				a.setStartTime((Date)e.getProperty("startDate"));
				a.setEndTime((Date)e.getProperty("endDate"));
				a.setStatus((String)e.getProperty("status"));
				a.setId(KeyFactory.keyToString(e.getKey()));
				results.add(a);
			}
			
		}
		return results;
	}
		
	public static List<Bid> ShowHistory(String buyerId){
		DatastoreService ds = DatastoreServiceFactory.getDatastoreService();

		Query query = new Query("Bid").addFilter("userId", Query.FilterOperator.EQUAL, buyerId).addSort("dateCreated",SortDirection.DESCENDING);
		Iterable<Entity> entities = ds.prepare(query).asIterable();
		List<Bid> items = new ArrayList<Bid>();
		for (Entity e : entities){
			 Bid b = new Bid();
			 b.setAuctionId((String)e.getProperty("auctionId"));
			 b.setDateCreated((Date)e.getProperty("dateCreated"));
			 b.setPrice((Double)e.getProperty("price"));
			 b.setUserId((String)e.getProperty("userId"));
			 b.setItemName((String)e.getProperty("itemName"));
			 items.add(b);
		}
		return items;
	}
	
	public static List<Bid> ShowActiveBids(String buyerId){
		DatastoreService ds = DatastoreServiceFactory.getDatastoreService();

		Query query = new Query("Bid").addFilter("userId", Query.FilterOperator.EQUAL, buyerId).addSort("dateCreated",SortDirection.DESCENDING);
		Iterable<Entity> entities = ds.prepare(query).asIterable();
		List<Bid> items = new ArrayList<Bid>();
		for (Entity e : entities){
			if (IsBidActive((String)e.getProperty("auctionId")) && 
					highestPriceForBid(items,(String)e.getProperty("auctionId")) < (Double)e.getProperty("price")){
				Bid b = new Bid();
				b.setAuctionId((String)e.getProperty("auctionId"));
				b.setDateCreated((Date)e.getProperty("dateCreated"));
				b.setPrice((Double)e.getProperty("price"));
				b.setUserId((String)e.getProperty("userId"));
				b.setItemName((String)e.getProperty("itemName"));
				items.add(b);
			}			 
		}
		return items;
	}
	
	public static double highestPriceForBid(List<Bid> items, String auctionId){
		double highest = 0;
		for(Bid b : items){
			if (b.getAuctionId().equals(auctionId)){
				if (highest < b.getPrice())
					highest = b.getPrice();
			}
		}
		return highest;
	}
	
	public static Boolean IsBidActive(String auctionId){
		DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
		
		try {
			Entity item = ds.get(KeyFactory.stringToKey(auctionId));
			String str = (String) item.getProperty("status");
			if (str.equals("Open"))
				return true;
			else
				return false;
		} catch (EntityNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
		
	}
	
	public static Boolean IsBidCancelled(String auctionId){
		DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
		
		try {
			Entity item = ds.get(KeyFactory.stringToKey(auctionId));
			String str = (String) item.getProperty("status");
			if (str.equals("Cancelled"))
				return true;
			else
				return false;
		} catch (EntityNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
		
	}
	
	public static Boolean IsBidUserUnsub(String auctionId){
		DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
		String status = "User Unsubscribed";
		
		try {
			Entity item = ds.get(KeyFactory.stringToKey(auctionId));
			String str = (String) item.getProperty("status");
			if (str.equals(status))
				return true;
			else
				return false;
		} catch (EntityNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
		
	}
	
	public static void CloseInactiveUserBid(String userId){
		DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
		
		Query query = new Query("Bid").addFilter("userId",Query.FilterOperator.EQUAL,userId);
		Iterable<Entity> entries = ds.prepare(query).asIterable();
		List<Key> keys = new ArrayList<Key>();
		for (Entity e : entries){
			keys.add(e.getKey());
		}
		ds.delete(keys);
	}
}
